Cognito IDP conector developer

Descripcion

Como utilizar el conector developer del cognito identity pool.

El conector developer nos permite obtener credenciales para acceder a los recursos de AWS a traves de un identificador de cuenta único, esto nos permite utilizar nuestro propio sistema de autenticación como intermediario entre el usuario y AWS, o tambien podemos usarlo para utilizar APIs de redes sociales que no poseen un metodo de autenticación federado.

Metodo

Lo primero que necesitamos es tener un usuario en AWS con el siguiente credencial:

AmazonCognitoDeveloperAuthenticatedIdentities

A continuación tenemos que generar un 'access key' para poder acceder como ese usuario (en nuestro caso desde el aws cli y desde node):

En cognito tenemos que tener creado nuestro conector developer (en este caso se llama TiktokIDP):

Obtener token desde AWS cli

Primero configuramos el aws cli para que utilice el usuario que acabamos de crear:

aws configure

Ahora solo tenemos que ejecutar el siguiente comando para obtener el access token de AWS:

aws cognito-identity get-open-id-token-for-developer-identity \
--identity-pool-id IDENTITY_POOL \
--logins "CONECTOR_IDP=USUARIO"

Cambiamos IDENTITY_POOL, CONECTOR_IDP y USUARIO, por los valores de nuestro proyecto, en nuestro caso CONECTOR_IDP sería TiktokIDP y USUARIO es cualquier string único que usaremos para identificar una cuenta, en el caso de que la cuenta no exista cognito la crea automaticamente y si ya existe nos devuelve los valores relacionados con dicha cuenta que hayamos indicado.

La solicitud nos devuelve un IdentityId y un Token, que se usarán para obtener un SESSION_TOKEN

Para obtener el SESSION_TOKEN lo hacemos con el siguiente comando:

aws cognito-identity get-credentials-for-identity \
--identity-id IDENTITY_ID \
--logins "cognito-identity.amazonaws.com=TOKEN"

Modificamos IDENTITY_ID y TOKEN con los valores que hemos obtenido en la solicitud anterior y la respuesta será algo como esto:

Dependiendo de la manera en la que vayamos a solicitar los recursos de AWS con el TOKEN inicial puede ser suficiente, pero si vamos a realizar la consulta final vamos a necesitar el SessionToken que nos devuelve esta consulta.

Obtener token con node

Para hacer lo mismo desde node primero tenemos que instalar el siguiente paquete:

npm install @aws-sdk/client-cognito-identity

El código es:

import { CognitoIdentityClient, GetOpenIdTokenForDeveloperIdentityCommand } from "@aws-sdk/client-cognito-identity";

const client = new CognitoIdentityClient({
  region: 'us-east-1',
  credentials: {
      accessKeyId: 'AKIAWC66EXGMUX5YO25J',
      secretAccessKey: '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',
    }
});

const input = {
  IdentityPoolId: 'us-east-1:1c9ff06a-ec20-4a3f-ac59-e194a13fa067',
  Logins: {
    "TiktokIDP": 'mi-username',
  },
  TokenDuration: 86400
};

const command = new GetOpenIdTokenForDeveloperIdentityCommand(input);
const response = await client.send(command);

console.log('IdentityID: ' + response.IdentityId)
console.log('Token: ' + response.Token)

Tenemos que modificar: region, accessKeyId, secretAccessKey, IdentityPoolId y el objeto Logins para indicar el nombre del conector developer y la cuenta de la que queremos obtener el token.

En este caso solo obtenemos el token y no el SessionToken, si usamos por ejemplo la librería de Amplify no necesitamos el SessionToken.

Obtener token a traves de una lambda con python

Para obtener el token desde una lambda de AWS usando python lo hacemos asi:

Primero en la lambda tenemos que configurar el permiso AmazonCognitoDeveloperAuthenticatedIdentities:

Y el código que usamos en la lambda sería:

import boto3
import json

def lambda_handler(event, context):
    init_cognito()
    
    return get_cognito_user()

def init_cognito():
    global client;
    client = boto3.client(
        'cognito-identity'
    )
    
def get_cognito_user():
    
    user = client.get_open_id_token_for_developer_identity(
        IdentityPoolId='us-east-1:1c9ff06a-ec20-4a3f-ac59-e194a13fa067',
        
        Logins={
            'TiktokIDP': 'mi-user'
        },
        TokenDuration=86400
    )
    
    if 'Token' and 'IdentityId' in user:
        aws_token = user['Token']
        identity_id = user['IdentityId']
    else:
        raise Exception('Error: cannot get user from Cognito IDP')

    return {
        'access_token': aws_token,
        'identity_id': identity_id
    }

Flujo para usar el conector developer con una API externa

Si queremos utilizar el IDP con una API como la de tiktok por ejemplo (que no provee autenticación federada), podemos hacerlo con un flujo como el siguiente:

La explicación es la siguiente

De esta manera hemos conseguido autenticarnos usando Tiktok en nuestra aplicación a traves del conector developer de cognito a pesar de que Tiktok no tiene una opción de login federado.

Tags

AWS | IDP | Cognito